package com.example.gcode;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.dropbox.client2.DropboxAPI;
import com.dropbox.client2.DropboxAPI.DropboxInputStream;
import com.dropbox.client2.DropboxAPI.Entry;
import com.dropbox.client2.DropboxAPI.ThumbFormat;
import com.dropbox.client2.DropboxAPI.ThumbSize;
import com.dropbox.client2.android.AndroidAuthSession;
import com.dropbox.client2.android.AuthActivity;
import com.dropbox.client2.exception.DropboxException;
import com.dropbox.client2.exception.DropboxIOException;
import com.dropbox.client2.exception.DropboxParseException;
import com.dropbox.client2.exception.DropboxPartialFileException;
import com.dropbox.client2.exception.DropboxServerException;
import com.dropbox.client2.exception.DropboxUnlinkedException;
import com.dropbox.client2.session.AccessTokenPair;
import com.dropbox.client2.session.AppKeyPair;
import com.dropbox.client2.session.Session.AccessType;
import com.dropbox.client2.session.TokenPair;
import com.gcloud.dropbox.ListDropBoxFile;
import com.gcloud.dropbox.UploadDropboxFile;
import com.gcloud.dto.GCloudFile;
import com.gcloud.googledrive.UploadGoogleFile;
import com.gcloud.persistance.SQLiteHandler;
import com.gfilechooser.utils.FileUtils;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.Drive.Files;
import com.google.api.services.drive.model.FileList;
import com.utils.Constants;
import com.utils.GCloudUtil;
import com.utils.Message;

import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;

public class DropBoxSyncronized extends Activity {
	private static String TAG = DropBoxSyncronized.class.getSimpleName();
	private ProgressDialog pDialog;	
	//Drive service;	
	private static final int REQUEST_ACCOUNT = 1;
	private static final int REQUEST_CODE = 100;

	/* DROP BOX THINGS */
	final static private String APP_KEY = "bx9eufdsdzpbxs5";
	final static private String APP_SECRET = "tz6vorkhj2xvfv1";
	public static boolean mLoggedIn = false;
	final static private String ACCOUNT_PREFS_NAME = "prefs";
	final static private String ACCESS_KEY_NAME = "ACCESS_KEY";
	final static private String ACCESS_SECRET_NAME = "ACCESS_SECRET";
	DropboxAPI<AndroidAuthSession> mApi;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.archivos_list);
		dropBoxAuthentication();
	}

	private void showChooser() {
		// Use the GET_CONTENT intent from the utility class
		Intent target = FileUtils.createGetContentIntent();
		// Create the chooser Intent
		Intent intent = Intent.createChooser(target,
				getString(R.string.chooser_title));
		try {
			startActivityForResult(intent, REQUEST_CODE);
		} catch (ActivityNotFoundException e) {
			// The reason for the existence of aFileChooser
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		Log.i("jalskjdf", "guaro!!");
		switch (item.getItemId()) {
		case R.id.menu_upload:

			Log.i("here", "upload");
			showChooser();
			break;
		case R.id.menu_download:
			Log.i("here", "download");
			break;
		case R.id.menu_delete:
			Log.i("here", "delete");
			break;
		case R.id.menu_bookmark:
			Log.i("here", "bookmark");
			break;
		case R.id.menu_save:
			Log.i("here", "save");
			break;
		case R.id.menu_search:
			Log.i("here", "search");
			break;
		case R.id.menu_google_drive:
			Log.i("here", "google drive");
			break;
		case R.id.menu_dropbox:
			Log.i("here", "dropbox");
			break;
		}
		return true;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		MenuInflater menuInflater = getMenuInflater();
		menuInflater.inflate(R.layout.menu_layout, menu);
		return true;
	}

	private void dropBoxAuthentication() {
		AndroidAuthSession session = buildSession();
		mApi = new DropboxAPI<AndroidAuthSession>(session);
		checkAppKeySetup();
//		if (DropBoxSyncronized.mLoggedIn) {
//			Log.i("v()", "is still logged");
//			new CargarArchivos().execute();
//		} else {
			Log.i("DropBoxAuthentication()", "is not logged");
			mApi.getSession().startAuthentication(DropBoxSyncronized.this);
//		}
		//setLoggedIn(mApi.getSession().isLinked());
		Log.i("DropBoxAuthentication", "Logged: "
				+ mApi.getSession().isLinked());		
	}

	private void callDropBoxList() {
		Log.i(TAG, "before to list");
		ListDropBoxFile listDropBox = new ListDropBoxFile(
				DropBoxSyncronized.this, mApi, "/");
		Log.i(TAG, "before to execute");
		listDropBox.execute();
		Log.i(TAG, "after execute");
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		switch (requestCode) {
		case REQUEST_ACCOUNT:
			if (resultCode == RESULT_OK && data != null
					&& data.getExtras() != null) {
			}
			break;
		case REQUEST_CODE:
			if (resultCode == RESULT_OK) {
				if (data != null) {
					// Get the URI of the selected file
					final Uri uri = data.getData();
					try {
						// Create a file instance from the URI
						final File file = FileUtils.getFile(uri);
						showToast("File selected: " + file.getAbsolutePath());
						UploadDropboxFile uploadDropBoxFile = new UploadDropboxFile(
								DropBoxSyncronized.this, mApi, "/", file);
						uploadDropBoxFile.execute();
						// UploadGoogleFile googleFile = new UploadGoogleFile(
						// service, Archivos.this, file);
						// googleFile.execute();
					} catch (Exception e) {
						Log.e("FileSelectorTestActivity", "File select error",
								e);
					}
				}
			}
			break;		
		}
	}

	@Override
	protected void onResume() {
		super.onResume();
		if (mApi.getSession() == null) {
			Log.i("onResume()", "session null");
			return;
		}
		AndroidAuthSession session = mApi.getSession();

		if (session.authenticationSuccessful()) {
			try {
				session.finishAuthentication();				
				TokenPair tokens = session.getAccessTokenPair();				
				storeKeys(tokens.key, tokens.secret);				
				try{
				new CargarArchivos().execute(tokens.key);
				}catch(Exception e){
					Log.e("DropboxSyncronized", "problems charging files: "+e!=null?e.getMessage():" error is null");
				}
			} catch (IllegalStateException e) {
				showToast("Couldn't authenticate with Dropbox:"
						+ e.getLocalizedMessage());
				Log.i(TAG, "Error authenticating", e);
			}
		}
	}

	public void showToast(final String toast) {
		runOnUiThread(new Runnable() {
			@Override
			public void run() {
				Toast.makeText(getApplicationContext(), toast,
						Toast.LENGTH_SHORT).show();
			}
		});
	}

	public void checkAppKeySetup() {
		if (APP_KEY.startsWith("CHANGE") || APP_SECRET.startsWith("CHANGE")) {
			showToast("You must apply for an app key and secret from developers.dropbox.com, and add them to the GCloud ap before trying it.");
			return;
		}
		Intent testIntent = new Intent(Intent.ACTION_VIEW);
		String scheme = "db-" + APP_KEY;
		String uri = scheme + "://" + AuthActivity.AUTH_VERSION + "/test";
		testIntent.setData(Uri.parse(uri));
		PackageManager pm = getPackageManager();
		if (0 == pm.queryIntentActivities(testIntent, 0).size()) {
			showToast("URL scheme in your app's "
					+ "manifest is not set up correctly. You should have a "
					+ "com.dropbox.client2.android.AuthActivity with the "
					+ "scheme: " + scheme);
		}
	}

	public AndroidAuthSession buildSession() {
		AppKeyPair appKeyPair = new AppKeyPair(APP_KEY, APP_SECRET);
		AndroidAuthSession session;
//		String[] stored = getKeys();
//		if (stored != null) {
//			Log.i("buildSession", " getting key stored:");
//			AccessTokenPair accessToken = new AccessTokenPair(stored[0],
//					stored[1]);
//			session = new AndroidAuthSession(appKeyPair, AccessType.DROPBOX,
//					accessToken);
//		} else {
//			Log.i("buildSession",
//					"getting key not stored, going to build a new one");
			session = new AndroidAuthSession(appKeyPair, AccessType.DROPBOX);
//		}
		if (session != null) {
			Log.i("buildSession", " session is not null");
		}
		return session;
	}

//	public String[] getKeys() {
//		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
//		String key = prefs.getString(ACCESS_KEY_NAME, null);
//		String secret = prefs.getString(ACCESS_SECRET_NAME, null);
//		if (key != null && secret != null) {
//			String[] ret = new String[2];
//			ret[0] = key;
//			ret[1] = secret;
//			return ret;
//		} else {
//			return null;
//		}
//	}

//	public void setLoggedIn(boolean loggedIn) {
//		DropBoxSyncronized.mLoggedIn = loggedIn;
//		Log.i("setLoggedIn() ", String.valueOf(mLoggedIn));
//	}

	public void storeKeys(String key, String secret) {
		// Save the access key for later
//		SharedPreferences prefs = getSharedPreferences(ACCOUNT_PREFS_NAME, 0);
//		Editor edit = prefs.edit();
//		edit.putString(ACCESS_KEY_NAME, key);
//		edit.putString(ACCESS_SECRET_NAME, secret);
//		edit.commit();
		SQLiteHandler sqliteHandler=new SQLiteHandler(getApplicationContext(),Constants.GCLOUD, null, Constants.DB_VERSION);
//		try {
			sqliteHandler.insertAccount(Constants.DROPBOX, key, key, secret);
//		} catch (DropboxException e) {
//			sqliteHandler.insertAccount(Constants.DROPBOX, Constants.DROPBOX, key, secret);
//		}
	}

	class CargarArchivos extends AsyncTask<String, String, String> {

		/**
		 * Before starting background thread Show Progress Dialog
		 * */
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			pDialog = new ProgressDialog(DropBoxSyncronized.this);
			pDialog.setMessage(Message.CHARGING_FILES);
			pDialog.setIndeterminate(false);
			pDialog.setCancelable(false);
			pDialog.show();
		}

		GCloudSingleton gCloudSingleton;
		private String mErrorMsg;
		private String mPath = "/";
		List<Entry> entriesFromDrive = new ArrayList<Entry>();

		/**
		 * getting Inbox JSON
		 * */
		protected String doInBackground(String... params) {
			String account=params[0];

			Log.i("GCLOUD", "Ya entre a doInBackground :)");
			try {
				// Get the metadata for a directory
				Log.i("doInBackGround", "working in background");
				executeQueryOnDrive(mPath);
				for (Entry dirent : entriesFromDrive) {
					GCloudUtil.context = DropBoxSyncronized.this;
					GCloudUtil.dropBoxToContentValue(dirent,account);
				}
				//gCloudSingleton = GCloudSingleton.getInstance();
				//gCloudSingleton.setFilesFromAllService(getRootFiles());

				// Entry dirent = mApi.metadata(mPath, 2500, null, true, null);
				// entriesFromDrive.add(dirent);
				// Log.i("doInBackGround", "after get service info");
				// if (!dirent.isDir || dirent.contents == null) {
				// // It's not a directory, or there's nothing in it
				// mErrorMsg = "File or empty directory";
				// Log.i("doInBackGround",mErrorMsg);
				// return "false";
				// }

				// Make a list of everything in it that we can get a thumbnail
				// for
				// ArrayList<Entry> thumbs = new ArrayList<Entry>();
				return "true";

			} catch (DropboxUnlinkedException e) {
				// The AuthSession wasn't properly authenticated or user
				// unlinked.
			} catch (DropboxPartialFileException e) {
				// We canceled the operation
				mErrorMsg = "Download canceled";
			} catch (DropboxServerException e) {
				// Server-side exception. These are examples of what could
				// happen,
				// but we don't do anything special with them here.
				if (e.error == DropboxServerException._304_NOT_MODIFIED) {
					// won't happen since we don't pass in revision with
					// metadata
				} else if (e.error == DropboxServerException._401_UNAUTHORIZED) {
					// Unauthorized, so we should unlink them. You may want to
					// automatically log the user out in this case.
				} else if (e.error == DropboxServerException._403_FORBIDDEN) {
					// Not allowed to access this
				} else if (e.error == DropboxServerException._404_NOT_FOUND) {
					// path not found (or if it was the thumbnail, can't be
					// thumbnailed)
				} else if (e.error == DropboxServerException._406_NOT_ACCEPTABLE) {
					// too many entries to return
				} else if (e.error == DropboxServerException._415_UNSUPPORTED_MEDIA) {
					// can't be thumbnailed
				} else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) {
					// user is over quota
				} else {
					// Something else
				}
				// This gets the Dropbox error, translated into the user's
				// language
				mErrorMsg = e.body.userError;
				if (mErrorMsg == null) {
					mErrorMsg = e.body.error;
				}
			} catch (DropboxIOException e) {
				// Happens all the time, probably want to retry automatically.
				mErrorMsg = "Network error.  Try again.";
			} catch (DropboxParseException e) {
				// Probably due to Dropbox server restarting, should retry
				mErrorMsg = "Dropbox error.  Try again.";
			} catch (DropboxException e) {
				// Unknown error
				mErrorMsg = "Unknown error.  Try again.";
			}
			return "false";

		}

		String globalMPath = "";

		private void executeQueryOnDrive(String root) throws DropboxException {
			Entry dirent = mApi.metadata(root, 2500, null, true, null);
//			DropboxInputStream thum = mApi.getThumbnailStream("/",
//					ThumbSize.ICON_32x32, ThumbFormat.JPEG);
			//byte[] imageInString=convertDropboxInputStreamToString(thum);
			
			entriesFromDrive.add(dirent);
			// Log.i("doInBackGround", "after get service info");
			if (!dirent.isDir || dirent.contents == null) {
				// It's not a directory, or there's nothing in it
				mErrorMsg = "File or empty directory";
				Log.i("doInBackGround", mErrorMsg);
			}
			mErrorMsg = "Size: " + dirent.contents.size() + " ";
			for (Entry ent : dirent.contents) {
				// Log.i("ListDropBox", ent.fileName() + " Is directory: "
				// + ent.isDir + " Path: " +
				// ent.path+" ParentPath: "+ent.parentPath());
				if (ent.isDir) {
					executeQueryOnDrive(root + ent.fileName() + "/");
				}
			}
		}

//		private byte [] convertDropboxInputStreamToString(
//				DropboxInputStream stream) {
//			ByteArrayOutputStream reader = new ByteArrayOutputStream();
//			int byteReader=0;
//			byte[] data=new byte[1024];
//			
//			try {
//				while((byteReader=stream.read(data, 0, data.length))!=-1){
//					reader.write(data,0, byteReader);
//				}
//				reader.flush();
//			} catch (IOException e) {
//				Log.i("Dropbox Sync",
//						"Imposible to change DropboxIS to String: "
//								+ (e != null ? e : ""));
//			}
//			return reader.toByteArray();
//		}
//
//		private List<GCloudFile> getRootFiles() throws DropboxException {
//			SQLiteHandler sqliteHandler = new SQLiteHandler(
//					DropBoxSyncronized.this, Constants.GCLOUD, null, Constants.DB_VERSION);
//			return sqliteHandler.getChildren("/");
//
//		}

		/**
		 * After completing background task Dismiss the progress dialog
		 * **/
		protected void onPostExecute(String file_url) {
			// dismiss the dialog after getting all products
			pDialog.dismiss();
			if (file_url.equalsIgnoreCase("true")) {
				showToast("everything well done");
				Intent newIntent = new Intent(DropBoxSyncronized.this,
						Archivos.class);
				startActivity(newIntent);
			} else {
				showToast("probably something goes wrong");
			}
		}

	}

}
